package Controller;

import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;

import javax.swing.DefaultListModel;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import Model.*;
import View.*;

/**
 * Controller
 * @author Johanna
 *
 */
public class AddressController {

	private ContactsList model;
	private ModifyWindow modifyWindow;
	private Window view;

	/** Constructor */
	AddressController(ContactsList model, Window view)
	{
		this.model = model;
		this.view = view;
		this.modifyWindow = new ModifyWindow(view);

		// Add listeners to the view
		view.addButtonListener(new ButtonListener());
		view.addListSelectedListener(new ListSelectedListener());
		view.addDeleteListener(new DeleteListener());
		view.addSortLetterListener(new SortLetterListener());
		view.addSortGroupListener(new SortGroupListener());
		view.addSortAlphaListener(new SortAlphaListener());
		view.addSendEmailListener(new SendEmailListener());
		view.addSeeHomepageListener(new SeeHomepageListener());
		view.addOpenModifyListener(new OpenModifyListener());
		modifyWindow.addSaveModifyListener(new SaveModifyListener());
	}

	/**
	 * ActionListener
	 * Class to save a contact
	 * @author Johanna
	 *
	 */
	class ButtonListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			// Create a new contact
			Contact c = new Contact();
			c.setFname(view.getFormPane().getFnameField());
			c.setLname(view.getFormPane().getLnameField());
			c.setNumber(view.getFormPane().getNumberField());
			c.setAddress(view.getFormPane().getAddressField());
			c.setGroup(view.getFormPane().getGroupField());
			c.setEmail(view.getFormPane().getEmailField());
			c.setHomepage(view.getFormPane().getHomepageField());

			// Save it in the list
			model.getListing().add(c);

			// Display a confirmation message to the user
			JOptionPane d = new JOptionPane();
			d.showMessageDialog(view.getFormPane(), "The contact "+ c.getFname() +" "+ c.getLname() + " is now saved in the address book.");

			view.reset(); // reset the fields

			// to update the JList of contacts
			view.getListPane().getListing().setModel(model.createDefaultList());
		}
	}

	/**
	 * ActionListener
	 * Class to select the contact and display its information
	 * @author Johanna
	 *
	 */
	class ListSelectedListener implements ListSelectionListener {

		@Override
		public void valueChanged(ListSelectionEvent arg0) {
			// TODO Auto-generated method stub
			int index = view.getListPane().getListing().getSelectedIndex();

			if (!arg0.getValueIsAdjusting() && index != -1) {	
				Contact c_current = new Contact();
				String[] info = view.getListPane().getListing().getSelectedValue().toString().split(" ");

				c_current = model.searchContact(info);

				view.getInfoPane().getInfo().setText("First name: ");
				view.getInfoPane().getInfo().append( c_current.getFname() );
				view.getInfoPane().getInfo().append("\n");
				view.getInfoPane().getInfo().append("Last name: ");
				view.getInfoPane().getInfo().append( c_current.getLname() );
				view.getInfoPane().getInfo().append("\n");
				view.getInfoPane().getInfo().append("Phone number: ");
				view.getInfoPane().getInfo().append(c_current.getNumber() );
				view.getInfoPane().getInfo().append("\n");
				view.getInfoPane().getInfo().append("Address: ");
				view.getInfoPane().getInfo().append(c_current.getAddress() );
				view.getInfoPane().getInfo().append("\n");
				view.getInfoPane().getInfo().append("Group: ");
				view.getInfoPane().getInfo().append(c_current.getGroup() );
				view.getInfoPane().getInfo().append("\n");
				view.getInfoPane().getInfo().append("E-Mail: ");
				view.getInfoPane().getInfo().append(c_current.getEmail() );
				view.getInfoPane().getInfo().append("\n");
				view.getInfoPane().getInfo().append("Homepage: ");
				view.getInfoPane().getInfo().append(c_current.getHomepage() );
			}
		}
	}

	/**
	 * ActionListener
	 * Class to delete a contact
	 * @author Johanna
	 *
	 */
	class DeleteListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			// To search the contact
			Contact c = new Contact();
			String[] info = view.getListPane().getListing().getSelectedValue().toString().split(" ");

			c = model.searchContact(info);

			model.deleteContact(c);

			int index = view.getListPane().getListing().getSelectedIndex();
			if (index != -1)
				((DefaultListModel)view.getListPane().getListing().getModel()).remove(index);
		}

	}

	/**
	 * ActionListener
	 * Class to sort the contacts by letters
	 * @author Johanna
	 *
	 */
	class SortLetterListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
			JComboBox combo = (JComboBox)e.getSource();
			String letter = (String)combo.getSelectedItem();

			if(letter == "Everyone")
			{
				// to display all the contacts
				view.getListPane().getListing().setModel(model.createDefaultList());
			}

			else
			{
				// to get from the list contacts only those which started
				// by the letter "letter"
				ArrayList<Contact> listLetter = new ArrayList<Contact>();
				listLetter = model.sortByLetter(letter);

				// to display them
				DefaultListModel defaultList = new DefaultListModel();
				String nameContact;
				StringBuilder sb = new StringBuilder();

				// To go through the ArrayList
				for(int i=0; i<listLetter.size(); i++) {

					sb.append( listLetter.get(i).getFname() ).append( " " ).append( listLetter.get(i).getLname() );

					nameContact = sb.toString();

					sb.setLength(0);

					// To add the name of the contact to the list
					defaultList.addElement(nameContact);
				}

				view.getListPane().getListing().setModel(defaultList);
			}
		}
	}

	/**
	 * ActionListener
	 * Class to sort the contacts by groups
	 * @author Johanna
	 *
	 */
	class SortGroupListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
			JComboBox combo = (JComboBox)e.getSource();
			String group = (String)combo.getSelectedItem();

			if( group == "Everyone")
			{
				// to display all the contacts
				view.getListPane().getListing().setModel(model.createDefaultList());
			}

			else
			{
				// to get from the list contacts only those who belong to the group "group"
				ArrayList<Contact> listGroup = new ArrayList<Contact>();
				listGroup = model.sortByGroup(group);

				// to display them
				DefaultListModel defaultList = new DefaultListModel();
				String nameContact;
				StringBuilder sb = new StringBuilder();

				// To go through the ArrayList
				for(int i=0; i<listGroup.size(); i++) {

					sb.append( listGroup.get(i).getFname() ).append( " " ).append( listGroup.get(i).getLname() );

					nameContact = sb.toString();

					sb.setLength(0);

					// To add the name of the contact to the list
					defaultList.addElement(nameContact);
				}

				view.getListPane().getListing().setModel(defaultList);
			}
		}
	}

	/**
	 * ActionListener
	 * Class to sort the contacts by alphabetical order
	 * @author Johanna
	 *
	 */
	class SortAlphaListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			ArrayList<Contact> listSorted = new ArrayList<Contact>();

			// to sort the list by alphabetical order
			listSorted = model.sortAlphaOrder();

			// to display it
			DefaultListModel defaultList = new DefaultListModel();
			String nameContact;
			StringBuilder sb = new StringBuilder();

			// To go through the ArrayList
			for(int i=0; i<listSorted.size(); i++) {

				sb.append( listSorted.get(i).getFname() ).append( " " ).append( listSorted.get(i).getLname() );

				nameContact = sb.toString();

				sb.setLength(0);

				// To add the name of the contact to the list
				defaultList.addElement(nameContact);
			}

			view.getListPane().getListing().setModel(defaultList);
		}
	}

	/**
	 * ActionListener
	 * Class to send an email to a user
	 * @author Johanna
	 *
	 */
	class SendEmailListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
			String mailTo = "";
			URI uriMailTo = null;

			// To search the contact
			Contact c = new Contact();
			String[] info = view.getListPane().getListing().getSelectedValue().toString().split(" ");

			c = model.searchContact(info);

			// to do the URL
			mailTo = c.getEmail();
			mailTo += "?subject=[ADDRESS BOOK] Contact";

			// Open the e-mail software
			if (Desktop.isDesktopSupported()) 
			{
				if (Desktop.getDesktop().isSupported(Desktop.Action.MAIL)) 
				{
					try {
						uriMailTo = new URI("mailto", mailTo, null);
						Desktop.getDesktop().mail(uriMailTo);
					} 
					catch (IOException ex) 
					{}
					catch (URISyntaxException ex)
					{}
				}
			}
		}
	}

	/**
	 * ActionListener
	 * Class to open the homepage of a user
	 * @author Johanna
	 *
	 */
	class SeeHomepageListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
			// to open the homepage
			Desktop desktop = null;
			java.net.URI url;

			// To search the contact
			Contact c = new Contact();
			String[] info = view.getListPane().getListing().getSelectedValue().toString().split(" ");

			c = model.searchContact(info);

			try 
			{
				// to open the homepage
				url = new java.net.URI(c.getHomepage());
				if (Desktop.isDesktopSupported())
				{
					desktop = Desktop.getDesktop();
					desktop.browse(url);
				}
			}
			catch (Exception ex) 
			{
				System.out.println(ex.getMessage());
			}
		}
	}

	/**
	 * ActionListener
	 * Class to open a new window to edit a contact
	 * @author Johanna
	 *
	 */
	class OpenModifyListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
			// To search the contact
			Contact c = new Contact();
			String[] info = view.getListPane().getListing().getSelectedValue().toString().split(" ");

			c = model.searchContact(info);

			// To open the window with the form
			//modifyWindow = new ModifyWindow(view);
			modifyWindow.run();

			modifyWindow.setFnameField(c.getFname());
			modifyWindow.setLnameField(c.getLname());
			modifyWindow.setNumberField(c.getNumber());
			modifyWindow.setAddressField(c.getAddress());
			modifyWindow.setEmailField(c.getEmail());
			modifyWindow.setHomepageField(c.getHomepage());
			modifyWindow.getComboGroups().setSelectedItem(c.getGroup());
		}

	}

	/**
	 * ActionListener
	 * Class for the action to edit a contact
	 * @author Johanna
	 *
	 */
	class SaveModifyListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			
			// To search the contact in the list
			Contact c = new Contact();
			String[] info = view.getListPane().getListing().getSelectedValue().toString().split(" ");
			c = model.getListing().get(model.searchContactIndex(info));

			System.out.println("found");
			// to save the changes
			c.setFname(modifyWindow.getFnameField());
			c.setLname(modifyWindow.getLnameField());
			c.setNumber(modifyWindow.getNumberField());
			c.setAddress(modifyWindow.getAddressField());
			c.setEmail(modifyWindow.getEmailField());
			c.setHomepage(modifyWindow.getHomepageField());
			c.setGroup(modifyWindow.getGroupField());

			// to update the JList of contacts
			view.getListPane().getListing().setModel(model.createDefaultList());

			// Display a confirmation message to the user
			JOptionPane d = new JOptionPane();
			d.showMessageDialog(modifyWindow, "The changes have been saved.");
		}

	}

}
